/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.rooster.chromosomeevaluator.common;

import java.util.ArrayList;
import org.jgap.Gene;
import org.jgap.IChromosome;
import org.rooster.manager.ResourceManager;
import org.rooster.manager.TaskManager;

/**
 *
 * @author Shanaka
 */
public class ScheduleMetrix {

    private boolean scheduleHasNoEmployeeDuplications = true;
    private int[][] scheduleMetrixArray;
    private ArrayList<int[]> duplications = new ArrayList<int[]>();
    private static ScheduleMetrix SingletonScheduleMetrix = new ScheduleMetrix();

    private ScheduleMetrix() {
        scheduleMetrixArray = new int[ResourceManager.TOTAL_NO_OF_EMPLOYEES][TaskManager.NO_OF_TIME_SLOTS];
    }

    public static ScheduleMetrix getScheduleMetrixInstance() {
        return SingletonScheduleMetrix;
    }

    private void reSetMetrixInstance() {
        scheduleHasNoEmployeeDuplications = true;
        scheduleMetrixArray = new int[ResourceManager.TOTAL_NO_OF_EMPLOYEES][TaskManager.NO_OF_TIME_SLOTS];
        duplications = new ArrayList<int[]>();

    }

    public void fillMetrix(IChromosome chromosome) {
        reSetMetrixInstance();
        int sectionNo = 0;
        int slotNo = 0;
        int employeeId = 0;
        int timeSlotStart = 0;
        int timeSlotLength = 0;
        Gene[] genes = chromosome.getGenes();

        for (int i = 0; i < TaskManager.NO_OF_SECTIONS; i++) {
            sectionNo = i + 1;
            for (int j = 0; j < TaskManager.NO_OF_TIME_SLOTS; j++) {
                slotNo = j;
                int requirement = TaskManager.getRequirement(i, j);
                timeSlotLength += requirement;
                for (int k = timeSlotStart; k < timeSlotLength; k++) {
                    employeeId = (Integer) genes[k].getAllele();
                    if (scheduleMetrixArray[employeeId - 1][slotNo] == 0) {
                        scheduleMetrixArray[employeeId - 1][slotNo] = sectionNo;
                    } else {
                        scheduleHasNoEmployeeDuplications = false;
                        if (Math.abs(scheduleMetrixArray[employeeId - 1][slotNo]) == sectionNo) {
                            duplications.add(new int[]{employeeId, slotNo, sectionNo});
                        } else {
                            duplications.add(new int[]{employeeId, slotNo, scheduleMetrixArray[employeeId - 1][slotNo], sectionNo});
                        }
                        scheduleMetrixArray[employeeId - 1][slotNo] = (-1 * sectionNo);
                    }
                }
                timeSlotStart += requirement;
            }
        }
    }

    public int getNumberOfDuplications() {
        return duplications.size();
    }

    public int getNumberOfDuplicayionsInSameSection() {
        int sameSectionDuplications = 0;
        for (int[] temp : duplications) {
            if (temp.length == 3) {
                sameSectionDuplications++;
            }
        }
        return sameSectionDuplications;
    }

    public int getNumberOfDuplicayionsInTwoSection() {
        int twoSectionDuplications = 0;
        for (int[] temp : duplications) {
            if (temp.length == 4) {
                twoSectionDuplications++;
            }
        }
        return twoSectionDuplications;
    }

    /**
     * @return the scheduleHasNoEmployeeDuplications
     */
    public boolean isScheduleHasNoEmployeeDuplications() {
        return scheduleHasNoEmployeeDuplications;
    }

    /**
     * @return the scheduleMetrixArray
     */
    public int[][] getScheduleMetrixArray() {
        return scheduleMetrixArray;
    }

    /**
     * @return the duplications
     */
    public ArrayList<int[]> getDuplicatonsList() {
        return duplications;
    }
}
